<?php if (!defined('CORE_DIR')) die('Wrong entry point!');

/* 
 * Copyright 2010 Anton Muraviev a.k.a kuromaisu
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *     http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * 
 */

// =============================================================================
// Section: Database Result Set
// =============================================================================

/* -----------------------------------------------------------------------------
 * Class: AeroDatabaseResult
 * -----------------------------------------------------------------------------
 *
 * Base query result class.
 *
 */
abstract class AeroDatabaseResult
{
	protected $result = null;
	protected $size = 0;
	protected $pointer = 0;
	
	/*
	 * Method: size
	 *
	 * Returns the number of objects this result set contains.
	 * 
	 * Returns:
	 * 	int	-	result set size.
	 */
	public function count()
	{
		return $this->size;
	}
	
	/*
	 * Method: fetch
	 *
	 * Fetches the next result in the set.
	 * 
	 * Parameters:
	 * 	string	-	results container type: *object*, *array* or *assoc*.
	 * 
	 * Return:
	 * 	misc	-	object, indexed array or associative array.
	 * 
	 * See also:
	 * 	<_fetch>
	 */
	public function fetch($container = 'object')
	{
		if ($row = $this->_fetch($container))
		{
			$this->pointer++;
		}
		
		return $row;
	}
	
	/*
	 * Method: fetchAll
	 * 
	 * Fetches all results fro the set.
	 * 
	 * Parameters:
	 * 	string	-	results container type: *object*, *array* or *assoc*.
	 * 
	 * Return:
	 * 	array	-	an array of either objects, indexed arrays or associative arrays.
	 * 
	 * See also:
	 * 	<_fetch>
	 */
	public function fetchAll($container = 'object')
	{
		$result = array();
		
		if ($this->pointer !== 0)
		{
			$this->_seek(0);
		}
		
		while ($row = $this->_fetch($container))
		{
			$result[] = $row;
		}
		
		$this->_seek($this->pointer);
		
		return $result;
	}
	
	/*
	 * Method: keysAndValues
	 * 
	 * Derives an associative array of all key => value pairs from the result set.
	 * 
	 * Parameters:
	 * 	string	-	(optional) column to use for key;
	 * 	string	-	(optional) column to use for value.
	 * 
	 * Returns:
	 * 	array 	-	associative array.
	 */
	public function keysAndValues($key_column = null, $value_column = null)
	{
		$result = array();
		
		if ($this->pointer !== 0)
		{
			$this->_seek(0);
		}
		
		if (is_null($key_column) && is_null($value_column))
		{
			while ($row = $this->_fetch('array'))
			{
				$key = array_shift($row);
				$result[$key] = count($row) > 0 ? array_shift($row) : $key;
			}
		}
		else
		{
			while ($row = $this->_fetch('assoc'))
			{
				$result[$row[$key_column]] = $row[$value_column];
			}
		}
		
		$this->_seek($this->pointer);
		
		return $result;
	}
	
	/*
	 * Method: seek
	 *
	 * Seeks for a specified result in the set.
	 * 
	 * Parameters:
	 * 	int	-	zero-based offset.
	 * 
	 * Returns:
	 * 	true	-	on success;
	 * 	false	-	on error.
	 * 
	 * See also:
	 * 	<_seek>
	 */
	public function seek($offset)
	{
		$this->pointer = $offset;
		return $this->_seek($offset);
	}
	
	/*
	 * Method: reset
	 *
	 * Same as seek(0).
	 * 
	 * Returns:
	 * 	true	-	on success;
	 * 	false	-	on error.
	 * 
	 * See also:
	 * 	<seek>
	 */
	public function reset()
	{
		return $this->_seek(0);
	}
	
	/*
	 * Method: _fetch
	 *
	 * Fetches one result item from the set.
	 * 
	 * _To_be_implemented_by_children_classes_.
	 */
	abstract protected function _fetch($container = 'object');
	
	/*
	 * Method: _seek
	 *
	 * Seeks for a specified result in the set.
	 * 
	 * _To_be_implemented_by_children_classes_.
	 */
	abstract protected function _seek($offset);
}